package com.hww.utils;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.helpers.MessageFormatter;
import org.springframework.util.StringUtils;

import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import java.util.function.Function;

/**
 * @Author: youdao.hww
 * @Date: 10/31/24
 * @Desc:
 */
public class CommonUtils {


    /**
     * 格式化一个带有占位符的字符串<br/>
     *
     * @param message 原始字符串,占位符通过{}标记
     * @param args    占位符替换值
     * @return 格式化后的字符串
     */
    public static String format(@Nonnull String message, Object... args) {
        return MessageFormatter.arrayFormat(message, args).getMessage();
    }

    /**
     * 将java对象转换成json字符串
     *
     * @param obj 准备转换的对象
     * @return json字符串
     */
    public static String beanToJson(@Nonnull Object obj) {
        return JSON.toJSONString(obj);
    }

    /**
     * 将json字符串转换成java对象
     *
     * @param json 准备转换的json字符串
     * @param cls  准备转换的类
     * @param <T>  泛型类
     * @return 泛型对象
     */
    public static <T> T jsonToBean(@Nonnull String json, Class<T> cls) {
        return JSON.parseObject(json, cls);
    }

    /**
     * 将一个Object强转为T<br/>
     *
     * @param object 对象
     * @param <T>    泛型类型
     * @return 强转后的T类型对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T covert(Object object) {
        return (T)object;
    }

    /**
     * 获得一个不带间隔符的UUID
     *
     * @return uuid
     */
    public static String getUuid() {
        return UUID.randomUUID().toString().replace("-", "").toUpperCase();
    }

    /**
     * 获取请求中的json数据字符串
     *
     * @param request 请求
     * @return 请求参数
     * @throws IOException io异常
     */
    public static String getRequestJsonParam(HttpServletRequest request) throws IOException {
        ByteArrayOutputStream result = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        InputStream inputStream = request.getInputStream();
        while ((length = inputStream.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }
        return String.valueOf(result);
    }

    /**
     * 间隔符
     */
    private static final String SEPERATOR = ":";

    /**
     * 产生key
     *
     * @param keys key
     * @return xx:xx 模式的key
     */
    public static String produceKey(String... keys) {
        StringBuilder key = new StringBuilder();
        if (keys.length == 1) {
            key = new StringBuilder(keys[0]);
        } else {
            for (int i = 0; i < keys.length - 1; i++) {
                key.append(keys[i]).append(SEPERATOR);
            }
            key.append(keys[keys.length - 1]);
        }
        return key.toString();
    }

    private static final char UNDERLINE = '_';

    /**
     * <p>
     * 串驼峰式 转下划线格式(小写)
     * camelToUnderline("userName") =  "user_name"
     * </p>
     *
     * @param param 需要转换的字符串
     * @return 转换好的字符串
     */
    public static String camelToUnderline(@Nonnull String param) {
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c) && i > 0) {
                sb.append(UNDERLINE);
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    /**
     * 下划线格式 转 串驼峰式
     *
     * @param param 需要转换的字符串
     * @return 转换好的字符串
     */
    public static String underlineToCamel(@Nonnull String param) {
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (c == UNDERLINE) {
                if (++i < len) {
                    sb.append(Character.toUpperCase(param.charAt(i)));
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 剔除数据库查询时带的%
     *
     * @param param 查询参数
     * @return 替换 % _ \后的参数
     */
    @Deprecated
    public static String encodeParameter(@NotNull String param) {
        if (StringUtils.isEmpty(param)) {
            return param;
        }
        return param.replaceAll("%", "\\\\%").replaceAll("_", "\\\\_").replaceAll("\\\\", "\\\\\\\\");
    }

    /**
     * 剔除数据库查询时带的%
     *
     * @param param 查询参数
     * @return 替换 % _ \后的参数
     */
    public static String encodeParam(@NotNull String param) {
        if (StringUtils.isEmpty(param)) {
            return param;
        }
        if(param.contains("\\")) {
            return param.replaceAll("\\\\", "\\\\\\\\");
        } else {
            return param.replaceAll("%", "\\\\%").replaceAll("_", "\\\\_");
        }
    }

    /**
     * 创建Bean
     *
     * @param tClass class对象
     * @param <T>    Bean类型
     * @return T对象
     */
    public static <T> T newInstance(@Nonnull Class<T> tClass) {
        T t;
        try {
            t = tClass.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
            throw new RuntimeException(CommonUtils.format("Create new instance of {} failed: {}", tClass, e.getMessage()));
        }
        return t;
    }

    /**
     * 判断给定所有元素是否为empty
     *
     * @param values 判断参数
     * @return 全为空返回true, 否则false
     */
    public static boolean isAllEmpty(final Object... values) {
        if (ArrayUtils.isEmpty(values)) {
            return true;
        }

        for (final Object val : values) {
            if (ObjectUtils.isNotEmpty(val)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 判断给定所有元素是否不为empty
     *
     * @param values 判断参数
     * @return 全不为空返回true, 否则false
     */
    public static boolean isAllNotEmpty(final Object... values) {
        if (ArrayUtils.isEmpty(values)) {
            return false;
        }

        for (final Object val : values) {
            if (ObjectUtils.isEmpty(val)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 当对象不为空时, 获取对应的值
     *
     * @param obj   对象
     * @param value 对象值的函数
     * @param <T>   对象类型
     * @param <V>   返回值类型
     * @return obj为null时返回null, 否则返回对象的值
     */
    public static <T, V> V notNullGet(T obj, @Nonnull Function<T, V> value) {
        return notNullGet(obj, value, null);
    }

    /**
     * 当对象不为空时, 获取对应的值
     *
     * @param obj          对象
     * @param value        对象值的函数
     * @param defaultValue 默认值
     * @param <T>          对象类型
     * @param <V>          返回值类型
     * @return obj为null时返回defaultValue, 否则返回对象的值
     */
    public static <T, V> V notNullGet(T obj, @Nonnull Function<T, V> value, V defaultValue) {
        if (obj == null) {
            return defaultValue;
        }
        return value.apply(obj);
    }

}
